#ifndef NETLIB_INETADDRESS_H
#define NETLIB_INETADDRESS_H

// sockaddr网络地址结构体封装类

#include "copyable.h"
#include "StringPiece.h"
#include <netinet/in.h>

namespace netlib
{

namespace net
{

namespace sockets
{

const struct sockaddr* sockaddr_cast(const struct sockaddr_in6* addr);

} // namespace sockets end


class InetAddress : public netlib::copyable
{
public:
    explicit InetAddress(uint16_t port = 0, bool loopbackOnly = false, bool ipv6 = false);

    InetAddress(StringArg ip, uint16_t port, bool ipv6 = false);

    explicit InetAddress(const struct sockaddr_in& addr) : addr_(addr)
    { }

    explicit InetAddress(const struct sockaddr_in6& addr) : addr6_(addr)
    { }

    // 返回协议族
    sa_family_t family() const { return addr_.sin_family; }

    string toIp() const; // 将IP信息转化成字符串

    string toIpPort() const; // 将IP以及端口信息转化成字符串

    uint16_t port() const; // 返回16位的主机字节序端口号

    // 将成员变量转化成通用的sockaddr指针返回
    const struct sockaddr* getSockAddr() const { return sockets::sockaddr_cast(&addr6_); }

    // 设置IPV6 sockaddr_in6的值
    void setSockAddrInet6(const struct sockaddr_in6& addr6) { addr6_ = addr6; }

    uint32_t ipv4NetEndian() const; // 返回32位的网络字节序IP地址

    // 返回16位的网络字节序端口地址
    uint16_t portNetEndian() const { return addr_.sin_port; }

    static bool resolve(StringArg hostname, InetAddress* result);

    void setScopeId(uint32_t scope_id);

private:
    union
    {
        struct sockaddr_in addr_;
        struct sockaddr_in6 addr6_;
    }; // union  end

}; // class InetAddress end

} // namespace net end

} // namespace netlib end

#endif